﻿Imports System

Namespace System.Workflow.ComponentModel
    Friend NotInheritable Class SynchronizationFilter
        Inherits ActivityExecutionFilter
        Implements IActivityEventListener([Of] EventArgs), IActivityEventListener([Of] ActivityExecutionStatusChangedEventArgs)
        ' Methods
        Public Overrides Function Execute(ByVal activity As Activity, ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            If (activity Is Nothing) Then
                Throw New ArgumentNullException("activity")
            End If
            activity.RegisterForStatusChange(Activity.LockCountOnStatusChangeChangedEvent, Me)
            activity.HoldLockOnStatusChange(Me)
            If executionContext.AcquireLocks(Me) Then
                Return Me.ExecuteActivityNow(executionContext)
            End If
            Return activity.ExecutionStatus
        End Function

        Private Function ExecuteActivityNow(ByVal context As ActivityExecutionContext) As ActivityExecutionStatus
            Return MyBase.NextActivityExecutorInChain(context.Activity).Execute(context.Activity, context)
        End Function

        Public Sub OnEvent(ByVal sender As Object, ByVal e As EventArgs)
            Dim context As ActivityExecutionContext = DirectCast(sender, ActivityExecutionContext)
            If ((context.Activity.ExecutionStatus = ActivityExecutionStatus.Executing) AndAlso (Me.ExecuteActivityNow(context) = ActivityExecutionStatus.Closed)) Then
                context.CloseActivity
            End If
        End Sub

        Public Sub OnEvent(ByVal sender As Object, ByVal e As ActivityExecutionStatusChangedEventArgs)
            Dim context As ActivityExecutionContext = [TryCast](sender,ActivityExecutionContext)
            If (context.Activity.HasPrimaryClosed AndAlso (context.Activity.LockCountOnStatusChange = 1)) Then
                context.ReleaseLocks(False)
                context.Activity.UnregisterForStatusChange(Activity.LockCountOnStatusChangeChangedEvent, Me)
                context.Activity.ReleaseLockOnStatusChange(Me)
            End If
        End Sub

    End Class
End Namespace

